/**
 * 
 */
package com.taobao.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.taobao.client.buyer.BoughtItemList;
import com.taobao.client.obj.TopTadget;
import com.taobao.client.pages.BuyerReturnGoods;
import com.taobao.client.pages.CloseOrder;
import com.taobao.client.pages.DelayDate;
import com.taobao.client.pages.GoodsConfirmation;
import com.taobao.client.pages.PriceChange;
import com.taobao.client.pages.RefundAgree;
import com.taobao.client.pages.RefundApply;
import com.taobao.client.pages.RefundGetGood;
import com.taobao.client.pages.RefundNoGetGood;
import com.taobao.client.pages.RefundReject;
import com.taobao.client.pages.RefundTermUpdate;
import com.taobao.client.util.PopBox;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 * 
 * @author hujingfei.pt@taobao.com
 */
public class PageApi implements EntryPoint {

	// A vertical panel whose contents change as users interact with the application.
	private VerticalPanel contentPanel;
	private String appKey = "wudangniu";
	private String appSecret = "wudangniu";

	private final static String TEST_URL = "http://gw.api.may.taobao.net/top/private/services/rest";
	private final static String DAILY_LOGIN_POST = "http://container.may.taobao.net/container/exShop?";
	
	public final static String SERVICE_CODE = "APP_SERVICE_SHOPEX";
	private final static String divId = "rootPanel";

	// Store some session-scope information and constants.
	private Data d;
	
	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {	
		
		contentPanel = new VerticalPanel();
		
		final RootPanel rootPanel = RootPanel.get(divId);
		rootPanel.addStyleName("alignCenter");
		rootPanel.add(contentPanel);
		
		d = new Data();
		
		// When the users access our site for the first time, we must determine whether the user has login or not.
		String queryString = Window.Location.getQueryString();
		
		// The user has already login.
		if (queryString != null && queryString.length() > 0) {
			String session = extractParam(queryString, "top_session=");
			String name = extractParam(queryString, "top_parameters=");

			// Store the session-scope information.
			RPC.getService().setSession(session, name,
					new AsyncCallback<String>() {
						@Override
						public void onFailure(Throwable caught) {
							PopBox.inform("Error", caught.getLocalizedMessage());
						}

						@Override
						public void onSuccess(String result) {
							if (History.getToken().equalsIgnoreCase("FirstPage")) {
								History.newItem("PageApi");
							}
						}
			});
		} else {
			// The user has not login yet.
			if (History.getToken().length() == 0) {
				History.newItem("FirstPage");
			}
		}
		
		// Register history-handling methods.
		History.addValueChangeHandler( new ValueChangeHandler<String>() {			
			
			public void onValueChange(ValueChangeEvent<String> arg0) {
				String tokenString = (String) arg0.getValue();
				
				if (tokenString != null) {
					// Once the history stack is updated, clear the contentPanel immediately.
					clearContent();
					// Make comparison with history tokens.
					if (tokenString.equalsIgnoreCase("FirstPage")) {
						displayGUI1();
				    } else if (tokenString.equalsIgnoreCase("PageApi")) {
						displayGUI2();
					} else if (tokenString.equalsIgnoreCase("PageLoginPage")) {
						initialize(initCallback);
					} else if (tokenString.equalsIgnoreCase(BuyerPage.HISTORY_ITEM)) {
						addContent(BuyerPage.getInstance(d));
					} else if (tokenString.equalsIgnoreCase("SellerPage")) {
						SellerPage.doHistory(tokenString, d, contentPanel);
					} else if (tokenString.equalsIgnoreCase(PriceChange.HISTORY)) {
						addContent(PriceChange.getPriceChagePanel());
					} else if (tokenString.equalsIgnoreCase(DelayDate.HISTORY_ITEM)) {
						addContent(DelayDate.getDelayDate());
					} else if (tokenString.equalsIgnoreCase(CloseOrder.HISTORY_ITEM)) {
						addContent(CloseOrder.getCloseOrder());
					} else if (tokenString.equalsIgnoreCase(RefundAgree.HISTORY_ITEM)) {
						addContent(RefundAgree.getRefundAgree());
					} else if (tokenString.equalsIgnoreCase(RefundReject.HISTORY_ITEM)) {
						addContent(RefundReject.getRefundReject());
					} else if (tokenString.equalsIgnoreCase(RefundApply.HISTORY_ITEM)) {
						RefundApply ra = (RefundApply) ((BoughtItemList) (BuyerPage.getInstance(d)
								.getBoughtTradePanel())).getRefundApplyPage();
						ra.simulate();
						addContent(ra);
					} else if (tokenString.equalsIgnoreCase(RefundTermUpdate.HISTORY_ITEM)) {
						addContent(((BoughtItemList) (BuyerPage.getInstance(d)
								.getBoughtTradePanel())).getUpdateRefundPage());
						// The buyer return the goods to the seller
					} else if (tokenString.equalsIgnoreCase(BuyerReturnGoods.HISTORY_ITEM)) {
						// Display the page of the buyer's return goods to the seller
						addContent((((BoughtItemList) (BuyerPage.getInstance(d))
								.getBoughtTradePanel()).getBuyerReturnGoods()));
					} else if (tokenString.equalsIgnoreCase(GoodsConfirmation.HISTORY_ITEM)) {
						// Display the page of the buyer's confirmation of the goods.
						addContent((((BoughtItemList) (BuyerPage.getInstance(d))
								.getBoughtTradePanel()).getGoodConfirmPage()));
					}else if(tokenString.equalsIgnoreCase(RefundGetGood.HISTORY_ITEM)){
						// Display the page of the buyer's confirmation of the goods.
						addContent(RefundGetGood.getRefundGetGood());
					}else if(tokenString.equalsIgnoreCase(RefundNoGetGood.HISTORY_ITEM)){
						// Display the page of the buyer's confirmation of the goods.
						addContent(RefundNoGetGood.getRefundNoGetGood());
					}
				} // end if tokenString is not null
			} // end method onValueChange
		});
		
		History.fireCurrentHistoryState();
	} // end method onModuleLoad
	
	private void displayGUI1(){
		clearContent();
		
		Label tip = new Label("按钮 卖家申请appkey 用于给卖家申请了appkey，按钮 直接登陆 用于用户直接登陆");
		FlexTable fx = new FlexTable();
		fx.setBorderWidth(2);
		fx.setCellPadding(5);
		fx.setCellSpacing(5);
		Button applyButton = new Button("卖家申请appkey");
		Button directButton = new Button("直接登陆");
		int row = 0, col = 0;
		fx.setWidget(row, col, tip);
		fx.getFlexCellFormatter().setColSpan(row, col, 2);
		fx.getFlexCellFormatter().setHorizontalAlignment(row, col, HasHorizontalAlignment.ALIGN_CENTER);
		row++;
		fx.setWidget(row, col, applyButton);
		fx.getFlexCellFormatter().setHorizontalAlignment(row, col, HasHorizontalAlignment.ALIGN_CENTER);
		col++;
		fx.setWidget(row, col, directButton);
		fx.getFlexCellFormatter().setHorizontalAlignment(row, col, HasHorizontalAlignment.ALIGN_CENTER);
		
		addContent(fx);
		
		applyButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent arg0) {
				// Apply sub-appkey.
				RPC.getService().applySubAppKey(appKey, "D:\\Downloads\\Archive\\Carver.jpg", new AsyncCallback<TopTadget>() {
					
					@Override
					public void onSuccess(TopTadget arg0) {
						appKey = arg0.getAppKey();
						appSecret = arg0.getAppSecret();
						initialize(initCallback);
					}
					
					@Override
					public void onFailure(Throwable caught) {
						PopBox.inform("Error", caught.getLocalizedMessage());
					}
				});
			}
		});
		
		directButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent arg0) {
				History.newItem("PageLoginPage");
			}
		});
	}
	
	public void displayGUI2(){
		clearContent();
		
		final Button sellerButton = new Button("我是卖家");
		sellerButton.addClickHandler(new SellerHandler());
		
		final Button buyerButton = new Button("我是买家");
		buyerButton.addClickHandler(new MyHandler());
		
		final HeadPanel buttonPanel = new HeadPanel(true);
		buttonPanel.add(sellerButton);
		buttonPanel.add(buyerButton);
		
		addContent(buttonPanel);
		
		RootPanel logoutRP = RootPanel.get("logout");
		Element element = logoutRP.getElement();
		HTML logout = HTML.wrap(element);
		logout.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				String domain = Window.Location.getHost();
				String url = Window.Location.getHref();
				
				url = url.substring(0, url.indexOf("#"));

				if (url.indexOf("?") > 0)
					url = url.substring(0, url.indexOf("?"));
				
				RPC.getService().logout(domain, url, new AsyncCallback<String>() {
					@Override
					public void onFailure(Throwable caught) {
						PopBox.error("Logout Error", caught.getLocalizedMessage());
					}

					@Override
					public void onSuccess(String result) {
						Window.Location.replace(result);
					}
				});
			}
		});

	}

	/**
	 * Add a widget to the content panel
	 * 
	 * @param w Widget to be added to the contentPanel.
	 */
	public void addContent(Widget w) {
		if (w != null)
			contentPanel.add(w);
	}

	/**
	 * Clear out the content panel.
	 */
	public void clearContent() {
		contentPanel.clear();
	}

	/**
	 * A handler(inner class) for the buyerButton.
	 * 
	 * @author hujingfei.pt
	 * 
	 */
	private class MyHandler implements ClickHandler {
		AsyncCallback<Boolean> initCallback = new AsyncCallback<Boolean>() {
			@Override
			public void onFailure(Throwable rs) {
				PopBox.error("Access Error", rs.getLocalizedMessage());
			}

			@Override
			public void onSuccess(Boolean result) {
				doSuccess();
			}
		};

		/**
		 * Fired when the user clicks on the sellerButton and buyerButton.
		 */
		public void onClick(ClickEvent event) {
			initialize(initCallback);
		}

		protected void doSuccess() {
			d.type = Data.BUYER;
			History.newItem(BuyerPage.HISTORY_ITEM);
		}
	}

	/**
	 * A handler(inner class) for the sellerButton.
	 * 
	 * @author hujingfei.pt
	 * 
	 */
	private class SellerHandler extends MyHandler {
		@Override
		protected void doSuccess() {
			d.type = Data.SELLER;
			History.newItem("SellerPage");
		}
	}
	
	/**
	 * Initialize
	 */
	private void initialize(AsyncCallback<Boolean> callback) {
		RPC.getService().init(TEST_URL, appKey, appSecret, DAILY_LOGIN_POST, callback);
	}
	
	private AsyncCallback<Boolean> initCallback = new AsyncCallback<Boolean>() {
		@Override
		public void onFailure(Throwable caught) {
			PopBox.error("Initialize Error", caught.getLocalizedMessage());
		}

		String domain = Window.Location.getHost();
		String url = Window.Location.getHref();

		@Override
		public void onSuccess(Boolean result) {
			if (url.indexOf("#") >= 0) {
				url = url.substring(0, url.indexOf("#"));
			}

			if (url.indexOf("?") >= 0)
				url = url.substring(0, url.indexOf("?"));

			RPC.getService().getLoginURL(domain, url,
					new AsyncCallback<String>() {
						@Override
						public void onFailure(Throwable caught) {
							PopBox.error("Login Error", caught.getLocalizedMessage());
						}

						@Override
						public void onSuccess(String result) {
							Window.Location.replace(result);
						}
			});
		}
	};

	/**
	 * Extract the value of the specified key from the query string part of the url.
	 * 
	 * @param queryString the query string. 
	 * @param key the key of the pair.
	 * @return If the key is found, return the value, or return null.
	 */
	private String extractParam(String queryString, String key) {
		int index1 = queryString.indexOf(key);
		if (index1 != -1) {
			index1 = index1 + key.length();
			int index2 = queryString.indexOf('&', index1);
			if (index2 == -1) {
				index2 = queryString.length();
			}
			return queryString.substring(index1, index2);
		}
		return null;
	}
}
